Skip to content

Convert nethost to C#129828

Draft
elinor-fung wants to merge 6 commits into
dotnet:mainfrom
elinor-fung:nethost-to-c
Draft

Convert nethost to C#129828
elinor-fung wants to merge 6 commits into
dotnet:mainfrom
elinor-fung:nethost-to-c

Conversation

@elinor-fung

@elinor-fung elinor-fung commented Jun 25, 2026

Copy link
Copy Markdown
Member

Convert nethost to C. This builds on #128420 and #129480 to fully convert nethost so it compiles and links as C-only — no C++ runtime dependency.

  • pal
    • Add a C pal_get_loaded_library (look up an already-loaded library without loading it). The C++ pal::get_loaded_library now delegates to it.
  • fxr_resolver
    • Convert the last C++-only piece, try_get_existing_fxr, to C.
    • Remove the thin C++ wrappers in fxr_resolver.cpp
    • Move load_fxr_and_get_delegate (used by comhost and ijwhost) into its own header load_fxr_and_get_delegate.h
  • nethost
    • Replace nethost.cpp with nethost.c using the shared host bits that have been converted to C. The RAII error_writer_scope_t is replaced by manual save/restore of the error writer.
  • Build
    • Split hostmisc into C/C++ sources and add a C-only hostmisc_c object library

macOS arm64 Release

Binary Baseline Branch Δ bytes Δ %
libnethost.a 1,097,312 268,360 −828,952 −75.5%
libnethost.dylib 92,368 89,088 −3,280 −3.6%

Note

This PR description was drafted by GitHub Copilot.

elinor-fung and others added 5 commits June 23, 2026 14:51
Add a C implementation of looking up an already-loaded library in the
current process, so callers that need to reuse an existing hostfxr (e.g.
nethost) can do so without the C++ pal:: surface.

- Add a pal_dll_t typedef and pal_get_loaded_library declaration in pal.h.
- Implement pal_get_loaded_library in pal.unix.c (dlopen RTLD_NOLOAD,
  dladdr to resolve the path, and the /proc/self/maps fallback) and
  pal.windows.c (GetModuleHandleW + a shared get_module_file_name helper
  factored out of pal_get_own_executable_path).
- Repoint the C++ pal::get_loaded_library wrappers at the new C function,
  removing the old C++ implementations and the proc-maps helper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Now that pal_get_loaded_library is available in C, move the last
fxr_resolver function that was still C++-only into fxr_resolver.c.

Add fxr_resolver_try_get_existing_fxr (declaration in fxr_resolver.h,
implementation in fxr_resolver.c) and make the C++
fxr_resolver::try_get_existing_fxr wrapper delegate to it. Drop the file
comment noting that try_get_existing_fxr had to stay in C++.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rewrite nethost.cpp as nethost.c using the C host APIs: trace_* for
tracing, fxr_resolver_try_get_existing_fxr / try_get_path_from_dotnet_root
/ try_get_path for resolution, and utils_get_directory. The RAII
error_writer_scope_t is replaced by saving and restoring the previous
error writer manually around the call, and pal::string_t buffers become
manually-managed pal_char_t* allocations.

Update nethost/CMakeLists.txt to build nethost.c. The compiled nethost
code is now C-only.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fxr_resolver.cpp held thin C++ wrappers (marshalling pal::string_t to and
from the pal_char_t* C API) over the fxr_resolver_* functions in
fxr_resolver.c. Remove them and have the remaining C++ callers use the C
API directly:

- hostfxr_resolver.cpp uses fxr_search_location and fxr_resolver_try_get_path
  directly (with direct utils.h/error_codes.h includes that were previously
  pulled in transitively through fxr_resolver.h).
- The load_fxr_and_get_delegate template (used by ijwhost and comhost) moves
  to its own header, load_fxr_and_get_delegate.h, and calls the C resolver
  functions. Its fxr handle is typed as pal_dll_t.

fxr_resolver.h is now a pure C header and fxr_resolver is C-only (no
fxr_resolver.cpp), which also drops it from the static singlefilehost
sources.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
nethost's own code is C, and after the previous change fxr_resolver is
C-only too, but nethost still linked the full hostmisc (which includes C++
translation units). That gave the nethost targets a C++ linker language, so
the clang++ driver added a dependency on the C++ runtime (libc++) and
libnethost.a embedded the unused C++ objects.

Split the hostmisc sources into C_SOURCES/CXX_SOURCES and add hostmisc_c, an
object library built from just the C sources. hostmisc and hostmisc::public
are unchanged for the C++ consumers (apphost, hostfxr, hostpolicy, etc.).

Point nethost/libnethost at hostmisc_c (+ minipal_objects, which object
libraries don't propagate transitively). The nethost targets now compile no
C++, link with the C driver, and have no libc++ dependency; libnethost.a
shrinks substantially by dropping the embedded C++ objects.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the nethost conversion to C-only by rewriting nethost in C, moving remaining fxr_resolver functionality to the C surface, and adding a C PAL helper to detect an already-loaded hostfxr without introducing a C++ runtime dependency.

Changes:

  • Replaced nethost.cpp with nethost.c, switching to the C host APIs and manually saving/restoring the trace error writer.
  • Added C pal_get_loaded_library (and pal_dll_t) and routed the existing C++ pal::get_loaded_library through it.
  • Removed fxr_resolver.cpp and moved the delegate-loading template to load_fxr_and_get_delegate.h; updated C++ callers to use the C fxr_resolver_* APIs directly.
Show a summary per file
File Description
src/native/corehost/nethost/nethost.cpp Removed C++ implementation of get_hostfxr_path.
src/native/corehost/nethost/nethost.c New C implementation of get_hostfxr_path using C host APIs.
src/native/corehost/nethost/CMakeLists.txt Switched nethost sources to C and updated link deps to hostmisc_c.
src/native/corehost/load_fxr_and_get_delegate.h New header containing the load_fxr_and_get_delegate C++ template previously in fxr_resolver.h.
src/native/corehost/ijwhost/ijwhost.cpp Updated include to use load_fxr_and_get_delegate.h.
src/native/corehost/comhost/comhost.cpp Updated include to use load_fxr_and_get_delegate.h.
src/native/corehost/hostmisc/pal.h Added pal_dll_t and the C pal_get_loaded_library declaration.
src/native/corehost/hostmisc/pal.windows.c Added pal_get_loaded_library implementation and refactored module-path helper.
src/native/corehost/hostmisc/pal.windows.cpp C++ pal::get_loaded_library now delegates to pal_get_loaded_library.
src/native/corehost/hostmisc/pal.unix.c Added pal_get_loaded_library implementation (dlopen RTLD_NOLOAD + dladdr, with /proc/self/maps fallback).
src/native/corehost/hostmisc/pal.unix.cpp C++ pal::get_loaded_library now delegates to pal_get_loaded_library.
src/native/corehost/hostmisc/CMakeLists.txt Split hostmisc C vs C++ sources and introduced hostmisc_c object library.
src/native/corehost/fxr_resolver.h Removed C++ wrapper surface; added C fxr_resolver_try_get_existing_fxr.
src/native/corehost/fxr_resolver.cpp Removed thin C++ wrapper implementation.
src/native/corehost/fxr_resolver.c Added C implementation of fxr_resolver_try_get_existing_fxr.
src/native/corehost/CMakeLists.txt Updated fxr_resolver interface target to stop compiling fxr_resolver.cpp.
src/native/corehost/apphost/static/CMakeLists.txt Dropped ../../fxr_resolver.cpp from sources.
src/native/corehost/apphost/standalone/hostfxr_resolver.cpp Switched from C++ wrappers to C fxr_resolver_try_get_path API.
src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs Updated comment to match renamed enum reference (fxr_search_location).

Copilot's findings

  • Files reviewed: 19/19 changed files
  • Comments generated: 4

Comment thread src/native/corehost/nethost/nethost.c
Comment thread src/native/corehost/hostmisc/pal.unix.c
Comment thread src/native/corehost/fxr_resolver.c Outdated
Comment thread src/native/corehost/fxr_resolver.c
- nethost.c: use %zu (not %d) for the size_t in the invalid-size trace.
- pal.unix.c: bound the /proc/self/maps %s read with an explicit field
  width so a pathological line can't overflow the buffer.
- fxr_resolver.c: initialize *out_fxr in fxr_resolver_try_get_existing_fxr,
  and drop the stale fxr_resolver.cpp reference from the file comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants